<script lang="ts" setup>
import { ref, nextTick } from "vue";

import { useVbenDrawer } from "@vben/common-ui";

import { message, Tree, Dropdown, Menu, MenuItem } from "ant-design-vue";

import { list } from "#/api/system/menu";
import { roleMenuIds, saveRoleMenu } from "#/api/system/rbac";
import { getAllNodeIds, getLeafNodeIds } from "#/util/tool";
import { CloseOutlined, MoreOutlined } from "@ant-design/icons-vue";

const record = ref();
const checkStrictly = ref<boolean>(false); //默认false层级关联
const expandedKeys = ref<any>([]); //展开跟折叠的key

const currentRecord = ref();
const treeRef = ref();
const treeData = ref([]);
const treeKeys = ref<string[]>([]);
const selectedKeys = ref<string[]>([]);

// 勾选的key
const checkedKeys = ref<string[]>([]);
// 勾选的key含半选
const halfCheckedKeys = ref<string[]>([]);
// 所有叶子节点key
const leafKeys = ref<string[]>([]);

interface Node {
  id: string; // 假设 id 是字符串类型，可以根据需要调整
  children?: Node[]; // children 是可选的，类型为 Node 数组
}

/**
 * api请求成功回调
 */
const handleFetchSuccess = () => {
  roleMenuIds({
    role_id: record.value.id,
    // app_code: props.app_code,
  }).then((res: any) => {
    // 1.0 设置的勾选节点只能为叶子节点
    checkedKeys.value = res.filter((item: any) => {
      return leafKeys.value.includes(item);
    });

    // 2.0 添加包含半选的KEY
    halfCheckedKeys.value = res;

  });
};



/**
 * 递归提取 id 集合
 * @param nodes - 节点数组
 * @returns - 提取的 id 数组
 */
const extractIds = (nodes: Node[]): string[] => {
  let ids: string[] = [];
  nodes.forEach((node) => {
    ids.push(node.id); // 添加当前节点的 id
    if (node.children) {
      ids = ids.concat(extractIds(node.children)); // 递归提取子节点的 id
    }
  });
  return ids;
};

/**
 * 所有子节点
 * @param data - 节点数组
 */
const findLeafNodeIds = (data: Node[]): void => {
  const leafNodeIds: string[] = []; // 明确指定为字符串数组
  const traverse = (nodes: Node[]): void => {
    nodes.forEach((node) => {
      // 如果没有 children，说明是叶子节点
      if (!node.children || node.children.length === 0) {
        leafNodeIds.push(node.id);
      } else {
        // 递归遍历子节点
        traverse(node.children);
      }
    });
  };

  traverse(data);
  leafKeys.value = leafNodeIds; // 假设 leafKeys 是一个响应式引用
};

const [Drawer, DrawerApi] = useVbenDrawer({
  onOpenChange(isOpen) {
    record.value = isOpen ? DrawerApi.getData()?.record : {};
    DrawerApi.setState({
      loading: true,
    });
    list({
      format:'tree',

    })
      .then((res) => {
        treeData.value = res ?? [];
        treeKeys.value = extractIds(res);
        findLeafNodeIds(res); //筛选叶节点
        expandedKeys.value = treeKeys.value; //展开所有节点
        // //DOM渲染完成后执行回调勾选
        nextTick(() => {
          handleFetchSuccess();
        });
      })
      .finally(() => {
        DrawerApi.setState({
          loading: false,
        });
      });
  },

  onConfirm() {
    DrawerApi.setState({
      loading: true,
      confirmLoading: true,
    });
    saveRoleMenu({role_id:record.value.id,menu_id:halfCheckedKeys.value})
      .then(() => {
        message.success("保存成功");
      })
      .finally(() => {
        DrawerApi.setState({
          loading: false,
          confirmLoading: false,
        });
      });
  },
});



/**
 * 点击复选框触发处理
 * @param mCheckedKeys
 */
 const handleCheck = (key:any, e:any) => {
  if (checkStrictly.value) {
    //1.0层级独立
    checkedKeys.value = key.checked ? key.checked : key;
    halfCheckedKeys.value = key.checked ? key.checked : key;
  } else {
    //1.1层级关联
    checkedKeys.value = key.checked ? key.checked : key;
    halfCheckedKeys.value = [...key, ...e.halfCheckedKeys];
  }
};


type MenuActionKey =
  | "checkAll"
  | "cancelCheck"
  | "openAll"
  | "closeAll"
  | "noRelation"
  | "isRelation";

interface MenuClickEvent {
  key: MenuActionKey;
}


/**
 * 扩展操作
 */
const extendMenuClick = ({ key }:MenuClickEvent) => {
  const actions = {
    checkAll: () => {
      // 选择全部
      checkedKeys.value = treeKeys.value;
      halfCheckedKeys.value = treeKeys.value;
    },
    cancelCheck: () => {
      // 取消全选
      checkedKeys.value = [];
      halfCheckedKeys.value = [];
    },
    openAll: () => {
      // 展开全部
      expandedKeys.value = treeKeys.value;
    },
    closeAll: () => {
      // 折叠全部
      expandedKeys.value = [];
    },
    noRelation: () => {
      // 层级关联
      checkStrictly.value = false;
    },
    isRelation: () => {
      // 层级独立
      checkStrictly.value = true;
    }
  };

  if (actions[key]) {
    actions[key](); // 执行对应的操作
  }
};


defineExpose(DrawerApi);
</script>
<template>
  <div>
    <Drawer class="w-[40%]" title="授权菜单" :closable="false">
      <template #title>
        <CloseOutlined class="left-close"  @click=""/>
        角色权限分配
        <Dropdown>
          <MoreOutlined class="right-more" />
          <template #overlay>
            <Menu @click="(event) => extendMenuClick(event)">
              <MenuItem key="checkAll">选择全部</MenuItem>
              <MenuItem key="cancelCheck">取消选择</MenuItem>
              <div class="line"></div>
              <MenuItem key="openAll">展开全部</MenuItem>
              <MenuItem key="closeAll">折叠全部</MenuItem>
              <div class="line"></div>
              <MenuItem key="noRelation" :disabled="!checkStrictly">层级关联</MenuItem>
              <MenuItem key="isRelation" :disabled="checkStrictly">层级独立</MenuItem>
            </Menu>
          </template>
        </Dropdown>
      </template>

      <Tree
        ref="treeRef"
        defaultExpandAll
        checkable
        :check-strictly="checkStrictly"
        :selected-keys="selectedKeys"
        @check="handleCheck"
        v-model:checkedKeys="checkedKeys"
        v-model:expanded-keys="expandedKeys"
        :click-row-to-expand="false"
        :tree-data="treeData"
        :field-names="{ title: 'name', key: 'value' }"
      />
    </Drawer>
  </div>
</template>

<style lang="less" scoped>
.line {
  width: 100%;
  height: 1px;
  border-bottom: 1px solid #f0f0f0;
}
.left-close {
  margin-right: 10px;
}
.left-close:hover {
  color: red; /* 将文本颜色设置为红色 */
  cursor: pointer;
}

.right-more {
  position: absolute;
  right: 20px;
}
</style>
